package com.metier.logique;

import java.awt.Image;

import javax.swing.JEditorPane;
import javax.swing.text.html.HTMLDocument;
import javax.swing.text.html.HTMLEditorKit;

/**
 * @name JGoogleMapEditorPan
 * @description JGoogleMapEditorPan est une classe permettant de récupérer un JEditorPane contentant une image d'une carte géographique retournée par GoogleMap.<br />
 * 				Carte d'un zoom de 12, de 630px de largeur et 450px de hauteur en vue du dessus de type Terrain.
 * 
 * @method JGoogleMapEditorPan - Constructeur par défaut - Initialisation du EditorKit
 * @method setZoom 
 * @method setRoadmap - Type de carte. Utiliser les constantes de classe VIEW_ pour les sélectionner.
 * @method getUrl - Retourne la dernière url générée.
 * @method setUrl
 * @method getWidth - Retourne la largeur.
 * @method setWidth
 * @method getHeight - Retourne la hauteur.
 * @method setHeight
 * @method getScale - Retourne la qualité d'image.
 * @method setScale - Qualité d'image.
 * @method getMapByCoordinate - Retourne une carte centrée sur les coordonnées GPS passées..
 * @method getMapByLocation - Retourne une carte centrée sur le couple ville/pays passé.
 * @method getMapByUrl - Génère la JGoogleMap pour une url donnée.
 * @method setMap - Assemble le code HTML en fonction des variables d'instances et l'insère dans l'objet courant. Retourne l'objet courant.
 * @method refresh - Rafraîchit le texte contenu par le JGoogleMapEditorPan. Accepte des paramètres pour les mettre à jour avant le refresh.
 * @method setHTML - Modifie le texte de l'EditorPan en y mettant une image pointant vers l'url courante.
 * 
 * @other
 * Exemple d'utilisation<br />
 * 		JGoogleMapEditorPan googleMap = new JGoogleMapEditorPan();
        try {
            JFrame frame = new JFrame();
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.add(googleMap.getMapByCoordinate("paris", "france"));
            frame.setSize(620, 480);
            frame.setLocation(200, 200);
            frame.setVisible(true);
            
        } catch (Exception ex) {
            Logger.getLogger(JGoogleMapEditorPan.class.getName()).log(Level.SEVERE, null, ex);
        }
 * @author Ambroise
 */
public class JGoogleMapEditorPan extends JEditorPane {

	/**
	 * serialVersionUID - Sert à Java.
	 */
	private static final long serialVersionUID = 1L;

	/*
	 * Variables privées de la classe.
	 */
	/**
	 * Zoom de la carte. 12 par défaut.
	 */
    private int zoom = 12;
    
    /**
     * Type de carte, à sélectionner avec les constantes de la classe.
     */
    private String roadmap = "terrain";
    
    /**
     * Largeur de la carte. 630px par défaut.
     */
    private int width = 630;
    
    /**
     * Hauteur de la carte. 450px par défaut.
     */
    private int height = 450;
    
    /**
     * Url de la dernière carte utilisée. Vide par défaut.
     */
    private String url = "";
    
    /**
     * Qualité de la carte entre 1 et 2 où 2 est une grande qualité. 1 par défaut.
     */
    private int scale = 1;
    
    /**
     * Position posX de la carte. (String ou Double ou int)
     */
    private String posX;
    
    /**
     * Position y de la carte. (String ou Double ou int)
     */
    private String posY;
    
	/*
     * Constantes de la classe.
     */
    public static final String VIEW_TERRAIN = "terrain";
    public static final String VIEW_SATELLITE = "satellite";
    public static final String VIEW_HYBRID = "hybrid";
    public static final String VIEW_ROADMAP = "roadmap";// Valeur utilisée par défaut.

    /**
     * Constructeur: Initialisation du EditorKit
     */
    public JGoogleMapEditorPan() {
        HTMLEditorKit kit = new HTMLEditorKit();
        HTMLDocument htmlDoc = (HTMLDocument) kit.createDefaultDocument();
        this.setEditable(false);
        this.setContentType("text/html");
        this.setEditorKit(kit);
        this.setDocument(htmlDoc);
        System.setProperty("http.proxyHost", "10.13.0.1");
        System.setProperty("http.proxyPort", "3128");
        System.setProperty("http.proxyUser","vrigah"); 
        System.setProperty("http.proxyPassword","vrigahvrigah");
    }

    /**
     * @name
     * @param int - zoom valeur de 0 à 21
     */
    public void setZoom(int zoom) {
    	if(zoom < 0){
        	this.zoom = 0;
        }else if(zoom > 21){
        	this.zoom = 21;
        }else{
        	this.zoom = zoom;
        }
    }

    /**
     * @name setRoadmap
     * @param String - roadMap
     */ public void setRoadmap(String roadMap) { this.roadmap = roadMap;
    }
    
    /**
     * @name getUrl
     * @description Retourne la dernière url générée.
     * @return String - url
     */
    public String getUrl() { return this.url; }

	/**
	 * @name setUrl
	 * @param String - url
	 */
	public void setUrl(String url) { this.url = url; }
	
    /**
     * @name getWidth
     * @description Retourne la largeur.
     * @return Int - width
     */
	public int getWidth() {
		return this.width;
	}

	/**
	 * @name setWidth
	 * @param int - width
	 */
	public void setWidth(int width) {
		this.width = width;
	}

    /**
     * @name getHeight
     * @description Retourne la hauteur.
     * @return int - height
     */
	public int getHeight() {
		return this.height;
	}

	/**
	 * @name setHeight
	 * @param int - height
	 */
	public void setHeight(int height) {
		this.height = height;
	}

	/**
     * @name getScale
     * @description Retourne la qualité d'image.
     * @return int - scale
     */
	public int getScale() {
		return this.scale;
	}

	/**
	 * @name setScale
	 * @description Qualité d'image.
	 * @param int - scale
	 */
	public void setScale(int scale) {
		if(scale < 1){
        	this.scale = 1;
        }else if(scale > 2){
        	this.scale = 2;
        }else{
        	this.scale = scale;
        }
	}

	public String getPosX() {
		return this.posX;
	}

	public void setPosX(String x) {
		this.posX = x;
	}

	public String getPosY() {
		return this.posY;
	}

	public void setPosY(String y) {
		this.posY = y;
	}

	/**
     * @name getMapByCoordinate
     * @description Retourne une carte centrée sur les coordonnées GPS passées.
     * @param String - latitude - Coordonnée x
     * @param String - longitude - Coordonnée y
     * 
     * @return JGoogleMapEditorPan - L'objet courant.
     * @throws Exception
     */
    public JGoogleMapEditorPan getMapByCoordinate(String latitude, String longitude) throws Exception {
        this.posX = latitude;
        this.posY = longitude;
    	return this.setMap();
    }

    /**
     * @name getMapByLocation
     * @description Retourne une carte centrée sur le couple ville/pays passé.
     * @param String - city - Nom de la ville
     * @param String - country - Nom du pays
     * 
     * @return JGoogleMapEditorPan - L'objet courant.
     * @throws Exception
     */
    public JGoogleMapEditorPan getMapByLocation(String city, String country) throws Exception {
        this.posX = city;
        this.posY = country;
    	return this.setMap();
    }
    
    
    /**
     * @name getMapByUrl
     * @description Génère la JGoogleMap pour une url donnée.
     * @param String - url - Url de la carte à afficher.
     */
    public JGoogleMapEditorPan getMapByUrl(MSG oMSG){
    	this.url = (String)oMSG.getData("url");
    	String[] urlSplited1 = this.url.split("center=");
    	String[] urlSplited2 = urlSplited1[1].split(",");
    	this.posX = urlSplited2[0].toString();
    	String[] urlSplitted3 = urlSplited2[1].split("&");
    	this.posY = urlSplitted3[0];

    	// On génère le code HTML.
    	setHTML();
    	
    	return this;
    }

    /**
     * @name setMap
     * @description Assemble le code HTML et l'insère dans l'objet courant.
     * 
     * @return JGoogleMapEditorPan - L'objet courant.
     * @throws Exception
     */
    private JGoogleMapEditorPan setMap() throws Exception {
    	// On appelle la méthode qui vérifie l'intégrité des positions X et Y.
    	verifierIntegritePositions();
    	
    	// On met à jour l'URL.
        this.url = "http://maps.googleapis.com/maps/api/staticmap?";
        this.url += "center=" + this.posX + "," + this.posY;// Coordonnées centrales de la carte.
        this.url += "&amp;zoom=" + this.zoom;// Zoom, initialement à 7.
        this.url += "&amp;size=" + this.width + "x" + this.height;// Taille de la carte.
        this.url += "&amp;maptype=" + this.roadmap;// Type de map désirée.
        this.url += "&amp;sensor=false";// On ne se fait pas géolocaliser par google.
        this.url += "&amp;scale=" + this.scale;// Haute résolution.

        // On génère le code HTML.
        setHTML();
        
        return this;
    }
    

    /**
     * @throws Exception 
     * @name refresh
     * @description Rafraîchit le texte contenu par le JGoogleMapEditorPan. Accepte des paramètres optionnels pour les mettre à jour avant le refresh.
     * 				MSG: "zoom" - Nouveau zoom.
     * 					 "roadmap" - Nouveau type de carte.
     * 					 "width" - Nouvelle largeur.
     * 					 "height" - Nouvelle longueur.
     * 					 "url" - Nouvelle url (Inutile à l'heure actuelle)
     * 					 "scale" - Nouvelle précision graphique (Attention, aggrandit fortement la taille de la carte, ne respecte plus width/height si différent de 1).
     	Exemple:
     			try {
					this.googleMapEditorPan.refresh(new MSG("roadmap", JGoogleMapEditorPan.VIEW_SATELLITE));
				} catch (Exception e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
     */
    public JGoogleMapEditorPan refresh(MSG oMSG) throws Exception{
    	// On met à jour les variables d'instance si elles sont fournies.
    	if(oMSG.getData("zoom") != null){
    		this.setZoom((Integer) oMSG.getData("zoom"));
    	}else if(oMSG.getData("roadmap") != null){
    		this.setRoadmap((String) oMSG.getData("roadmap"));
    	}else if(oMSG.getData("width") != null){
    		this.setWidth((Integer) oMSG.getData("width"));
    	}else if(oMSG.getData("height") != null){
    		this.setHeight((Integer) oMSG.getData("height"));
    	}else if(oMSG.getData("url") != null){
    		this.setUrl((String) oMSG.getData("url"));
    	}else if(oMSG.getData("scale") != null){
    		this.setScale((Integer) oMSG.getData("scale"));
    	}
    	
    	return setMap();
    }
    
    /**
     * @name setHTML
     * @description Modifie le texte de l'EditorPan en y mettant une image pointant vers l'url courante.
     */
    private void setHTML(){
    	String html = "<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN'>";
        html += "<html><head></head><body>";
        html += "<img src='" + this.url + "'>";
        html += "</body></html>";
        this.setText(html);
    }
    
    /**
     * 
     */
    public void verifierIntegritePositions(){
    	this.posX = this.posX.replaceAll(",","%20");
    	this.posX = this.posX.replaceAll("&","%20");
    	this.posX = this.posX.replaceAll(" ","%20");
    	
    	this.posY = this.posY.replaceAll(",","%20");
    	this.posY = this.posY.replaceAll("&","%20");
    	this.posY = this.posY.replaceAll(" ","%20");
    }
}